import java.sql.*;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.logging.Logger;

class CleanTask extends Thread {
    
    public boolean initOk;
    
    public CleanTask(){
        initOk = true;
        Log.debug("Clean thread init ok.");
    }
    
    private void intervalSleep(int seconds) {
        while (!CleanSystem.flagShutdown && seconds > 0 ) {
            try {
                Thread.sleep(1000);
                seconds --;
            } catch (InterruptedException e) {
                Log.except(e);
            }
        }
    }
    
    public void run(){
        while(!CleanSystem.flagShutdown){
            
            try {
                Connection conn = DriverManager.getConnection(Property.primaryDbURL, Property.username, Property.password);
                Statement stmt = conn.createStatement();
                ResultSet rs = stmt.executeQuery(
                    "select count(*) " +
                    "from pg_partition " +
                    "where parentid = (select oid from pg_class where relname = 'network') and " +
                    "      parttype = 'p'");
                rs.next();
                int partitionNumber = rs.getInt(1);
                int count = partitionNumber - Property.tablePartCount;
                if (count > 0) {
                    Log.info("partition number exceeds " + count + ", threshold(" + Property.tablePartCount + ")");
                    rs = stmt.executeQuery(
                        "select relname, boundaries[1]::text " +
                        "from pg_partition " +
                        "where parentid = (select oid from pg_class where relname = 'network') and " +
                        "      parttype = 'p' " +
                        "order by boundaries asc " +
                        "limit " + count); 
                    
                    while (rs.next()) {
                        String partitionName = rs.getString(1);
                        String boundary = rs.getString(2);
                        String sql = "alter table network drop partition " + partitionName;
                        Log.info(sql + "; -- boundary:" + boundary);
                        stmt.executeQuery(sql);
                    }
                } else {
                    Log.debug("partition number is " + partitionNumber + ", does not exceed threshold(" + Property.tablePartCount +")" );
                }
                
                stmt.close();
                conn.close();
                
            } catch (SQLException e) {
                Log.except(e);
            }
            
            intervalSleep(60);
        }
    }
}


public class CleanSystem{
    public static CleanTask task;
    
    public static boolean flagShutdown = false;

    public static boolean init() {
        Log.info("Clean System initing.");
        task = new CleanTask();
        if (task.initOk) {
            Log.info("Clean System init ok.");
        } else {
            Log.err("Clean System init failed.");
        }
        return task.initOk;
    }
    
    public static void run() {
        task.start();
        Log.info("Clean System start.");
    }
    
    public static void shutdown(){
        flagShutdown = true;
        Log.info("Clean System shutdown.");
    }
}
